package IO.操作文件;

//编写FilterInputStream
//我们也可以自己编写FilterInputStream，以便可以把自己的FilterInputStream“叠加”到任何一个InputStream中。
//
//下面的例子演示了如何编写一个CountInputStream，它的作用是对输入的字节进行计数：
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import java.io.*;
public class 使用Filter {
    public static void main(String[] args) throws IOException {
   	 //ZipEntry
        byte[] data = "hello, world!".getBytes("UTF-8");
        try (CountInputStream input = new CountInputStream(new ByteArrayInputStream(data))) {
            int n;
            //int read()方法会读取输入流的下一个字节，并返回字节表示的int值（0~255）。如果已读到末尾，返回-1表示不能继续读取了。
            while ((n = input.read()) != -1) {
                System.out.println((char)n);
            }
            System.out.println("Total read " + input.getBytesRead() + " bytes");
        }
    }
}

class CountInputStream extends FilterInputStream {
    private int count = 0;
   
    CountInputStream(InputStream in) {
    /*
     public class FilterInputStream extends InputStream {
       protected volatile InputStream in;
       protected FilterInputStream(InputStream in) {
           this.in = in;
       }
		}*/
   	//调用父类FilterInputStream的构造函数，参数相当于：InputStream in=new ByteArrayInputStream(data)
        super(in);
    }

    public int getBytesRead() {
        return this.count;
    }

    public int read() throws IOException {
        int n = in.read();
        if (n != -1) {
            this.count ++;
        }
        return n;
    }

    public int read(byte[] b, int off, int len) throws IOException {
        int n = in.read(b, off, len);
        if (n != -1) {
            this.count += n;
        }
        return n;
    }
}
//注意到在叠加多个FilterInputStream，我们只需要持有最外层的InputStream，并且，当最外层的InputStream关闭
//时（在try(resource)块的结束处自动关闭），内层的InputStream的close()方法也会被自动调用，并最终调用到最核心
//的“基础”InputStream，因此不存在资源泄露。